#include  "Typedef.h"
#include  "board.h"
#include  "hal_avr.h"
#include  "hal_Spi.h"
#include  "hal_int.h"


//----------------------------------------------------------------------------------
//  void halSpiInit(INT8U clockrate)
//
//  DESCRIPTION:
//    Initialize the MCU's IO for SPI communication
//  
//  ARGUMENTS:
//    clockrate   -  the  SPI speed
//
//  RETURNS:
//    None
//----------------------------------------------------------------------------------
void halSpiInit(INT8U clockrate)
{
    volatile INT8U temp;
    MCU_IO_OUTPUT(SPI_MOSI_PORT , SPI_MOSI_PIN , 0);
    MCU_IO_OUTPUT(SPI_SCK_PORT , SPI_SCK_PIN, 0);
    MCU_IO_OUTPUT(SPI_CSN_PORT , SPI_CSN_PIN, 1);
    MCU_IO_INPUT(SPI_MISO_PORT , SPI_MISO_PIN);
    MCU_IO_OUTPUT(SPI_SS_PORT,SPI_SS_PIN,1);
    //clockrate fck/2
    SPCR = BV(SPE)|(BV(MSTR));
    SPSR = BV(SPI2X);
    SPSR = 0x00;
    
    temp = SPDR;
}
//----------------------------------------------------------------------------------
//  INT8U halSpiWrite(INT8U addr, const INT8U *buffer, INT8U length)
//
//  DESCRIPTION:
//    Write data to device, starting at internal device address "addr".
//    The device will increment the address internally for every new byte
//    that is written. For single byte write, set length to 1.
//
//  ARGUMENTS:
//    addr   -  The device register address 
//    data   -  The pointer to the data start address
//    length -  The data length
//
//  RETURNS:
//    None
//----------------------------------------------------------------------------------
INT8U halSpiWrite(INT8U addr, const INT8U* data, INT8U length)
{
    INT8U i;
    INT8U rc;
    INT8U s;

    HAL_INT_LOCK(s);

    HAL_SPI_BEGIN;
    
    
    HAL_SPI_TXBUF_SET(addr);
    HAL_SPI_WAIT_TXFIN;
    rc = HAL_SPI_RXBUF;
    for (i = 0; i < length; i++)
    {
      HAL_SPI_TXBUF_SET(data[i]);
      HAL_SPI_WAIT_TXBUF;
    }

    HAL_SPI_END;

    HAL_INT_UNLOCK(s);

    return(rc);

}

//----------------------------------------------------------------------------------
//  INT8U halSpiRead(INT8U addr, INT8U* data, INT8U length)
//
//  DESCRIPTION:
//    Read data from device, starting at internal device address "addr".
//    The device will increment the address internally for every new byte
//    that is read. Note that the master device needs to write a dummy byte
//    (in this case 0) for every new byte in order to generate the clock to
//    clock out the data. For single byte read, set length to 1.
//
//  ARGUMENTS:
//    addr   -  The device register address 
//    data   -  The pointer to the data start address
//    length -  The data length
//
//  RETURNS:
//    None
//----------------------------------------------------------------------------------
INT8U halSpiRead(INT8U addr, INT8U* data, INT8U length)
{
    INT8U i;
    INT8U rc;
    INT8U  s;

    HAL_INT_LOCK(s);
    
    HAL_SPI_BEGIN;

    
    HAL_SPI_TXBUF_SET(addr);
    HAL_SPI_WAIT_TXFIN;
    rc = HAL_SPI_RXBUF;
    for (i = 0; i < length; i++)
    {
        HAL_SPI_TXBUF_SET(0);        // Dummy write to read data byte
        HAL_SPI_WAIT_TXFIN;
        data[i] = HAL_SPI_RXBUF;     // Store data from last data RX
    }

    HAL_SPI_END;

    HAL_INT_UNLOCK(s);

    return(rc);
}


//----------------------------------------------------------------------------------
//  INT8U halSpiStrobe(INT8U cmd)
//
//  DESCRIPTION:
//    Special write function, writing only one byte (cmd) to the device.
//
//  ARGUMENTS:
//    cmd    -  The device register commend 
//
//  RETURNS:
//    None
//----------------------------------------------------------------------------------
INT8U halSpiStrobe(INT8U cmd)
{
    INT8U rc;
    INT8U  s;

    HAL_INT_LOCK(s);

    HAL_SPI_BEGIN;

    
    HAL_SPI_TXBUF_SET(cmd);
    HAL_SPI_WAIT_TXFIN;
    rc = HAL_SPI_RXBUF;

    HAL_SPI_END;

    HAL_INT_UNLOCK(s);

    return(rc);
}
